package com.aizuda.boot.modules.business.feishu.service.impl;

import com.aizuda.boot.config.properties.FeiShuConfigProperties;
import com.aizuda.boot.modules.business.contract.entity.ContractTypeEntity;
import com.aizuda.boot.modules.business.contract.mapper.ContractFieldValueMapper;
import com.aizuda.boot.modules.business.feishu.FeiShuApproval;
import com.aizuda.boot.modules.business.feishu.domain.approval.CreateApprovalDTO;
import com.aizuda.boot.modules.business.feishu.domain.approval.SendFeiShuBotDTO;
import com.aizuda.boot.modules.business.feishu.domain.approval.SynchronizationApprovalDTO;
import com.aizuda.boot.modules.business.feishu.domain.entity.FeiShuApprovalCode;
import com.aizuda.boot.modules.business.feishu.domain.entity.FeiShuApprovalMessage;
import com.aizuda.boot.modules.business.feishu.mapper.FeiShuApprovalCodeMapper;
import com.aizuda.boot.modules.business.feishu.mapper.FeiShuApprovalMessageMapper;
import com.aizuda.boot.modules.business.feishu.service.FeiShuApprovalService;
import com.aizuda.boot.modules.business.performance.mapper.ContractTypeMapper;
import com.aizuda.boot.modules.common.constant.enums.FeiShuInstanceStatus;
import com.aizuda.boot.modules.common.constant.enums.FeiShuTaskStatus;
import com.aizuda.boot.modules.common.constant.enums.SystemFieldsEnum;
import com.aizuda.boot.modules.flw.entity.FlwProcessCategory;
import com.aizuda.boot.modules.flw.entity.FlwProcessConfigure;
import com.aizuda.boot.modules.flw.service.IFlwProcessCategoryService;
import com.aizuda.boot.modules.flw.service.IFlwProcessConfigureService;
import com.aizuda.boot.modules.flw.service.IFlwProcessService;
import com.aizuda.boot.modules.system.service.ISysUserService;
import com.aizuda.bpm.engine.FlowLongEngine;
import com.aizuda.bpm.engine.core.FlowCreator;
import com.aizuda.bpm.engine.core.enums.InstanceEventType;
import com.aizuda.bpm.engine.core.enums.TaskEventType;
import com.aizuda.bpm.engine.entity.*;
import com.baomidou.kisso.security.token.SSOToken;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Supplier;

/**
 * @Author sangyirong
 * @ClassName FeiShuApprovalServiceImpl
 * @Version 1.0
 * @Date 2025/8/2 17:33
 */
@Slf4j
@Service
public class FeiShuApprovalServiceImpl implements FeiShuApprovalService {

    @Resource
    private FeiShuConfigProperties feiShuConfigProperties;

    @Resource
    @Lazy
    private IFlwProcessService flwProcessService;

    @Resource
    private IFlwProcessConfigureService flwProcessConfigureService;

    @Resource
    private IFlwProcessCategoryService flwProcessCategoryService;

    @Resource
    private FeiShuApproval feiShuApproval;

    @Resource
    private FeiShuApprovalCodeMapper feiShuApprovalCodeMapper;

    @Resource
    private ContractFieldValueMapper contractFieldValueMapper;

    @Resource
    private FlowLongEngine flowLongEngine;

    @Resource
    private ContractTypeMapper contractTypeMapper;

    @Resource
    private FeiShuApprovalMessageMapper feiShuApprovalMessageMapper;

    @Resource
    private ISysUserService sysUserService;

    @Override
    public Boolean createProcess(Long processId, FlowCreator flowCreator) {
        log.info("开始创建飞书审批定义[{}]", processId);
        if (null == feiShuConfigProperties || CollectionUtils.isEmpty(feiShuConfigProperties.getApps())) {
            log.warn("飞书配置为空,创建失败");
            return false;
        }
        if (null == processId) {
            log.warn("processId为空,创建失败");
            return false;
        }
        FlwProcess process = flwProcessService.getById(processId);
        if (null == process) {
            log.warn("流程定义[{}]不存在", processId);
            return false;
        }
        FlwProcessConfigure configure = flwProcessConfigureService.getByProcessId(processId);
        if (null == configure) {
            log.warn("流程定义[{}]配置不存在", processId);
            return false;
        }
        FlwProcessCategory category = flwProcessCategoryService.getById(configure.getCategoryId());
        if (null == category) {
            log.warn("流程定义[{}]分类不存在", processId);
            return false;
        }
        feiShuConfigProperties.getApps().forEach((item, feiShuAppConfig) -> {
            CreateApprovalDTO dto = new CreateApprovalDTO();
            dto.setTenantKey(feiShuAppConfig.getTenantKey());
            dto.setApprovalName(process.getProcessName());
            dto.setApprovalCode(process.getProcessKey());
            dto.setGroupName(category.getName());
            dto.setGroupCode(String.valueOf(category.getId()));
            dto.setDescription(null != process.getRemark() ? process.getRemark() : "暂无描述。");
            dto.setBizType(process.getProcessType());
            try {
                String approvalCode = feiShuApproval.createApproval(dto);
                if (!StringUtils.hasText(approvalCode)) {
                    log.warn("【{}】创建飞书审批定义失败,审批定义编码为空", feiShuAppConfig.getName());
                    return;
                }
                FeiShuApprovalCode feiShuApprovalCode = feiShuApprovalCodeMapper.selectByUniqueKey(category.getId(), process.getProcessKey(), feiShuAppConfig.getTenantKey());
                if (null == feiShuApprovalCode) {
                    feiShuApprovalCode = new FeiShuApprovalCode();
                    feiShuApprovalCode.setCategoryId(category.getId());
                    feiShuApprovalCode.setProcessKey(process.getProcessKey());
                    feiShuApprovalCode.setTenantKey(feiShuAppConfig.getTenantKey());
                    feiShuApprovalCode.setApprovalCode(approvalCode);
                    feiShuApprovalCode.setCreatorId(Long.parseLong(flowCreator.getCreateId()));
                    feiShuApprovalCode.setCreateTime(new Date());
                } else {
                    feiShuApprovalCode.setApprovalCode(approvalCode);
                    feiShuApprovalCode.setUpdateId(Long.parseLong(flowCreator.getCreateId()));
                    feiShuApprovalCode.setUpdateTime(new Date());
                }
                feiShuApprovalCodeMapper.insertOrUpdate(feiShuApprovalCode);
                log.info("【{}】创建飞书审批定义成功,审批定义编码:{}", feiShuAppConfig.getName(), approvalCode);
            } catch (Exception e) {
                log.error("【{}】创建飞书审批定义失败", feiShuAppConfig.getName(), e);
            }
        });
        return true;
    }


    @Override
    public Boolean launchProcess(Long instanceId) {
        log.info("发起流程，开始同步数据到飞书审批");
        if (null == instanceId) {
            log.info("instanceId为空,发起失败");
            return false;
        }
        // 查询关联的合同
        Integer contractId = getContractIdByInstanceId(instanceId);
        if (null == contractId) {
            log.info("未找到关联的合同,发起失败");
            return false;
        }
        String contractName = contractFieldValueMapper.getFieldValueByCode(contractId, SystemFieldsEnum.CONTRACT_NAME.getCode());
        String applyPeople = contractFieldValueMapper.getFieldValueByCode(contractId, SystemFieldsEnum.APPLY_PEOPLE.getCode());
        // 查询流程实例
        FlwInstance instance = flowLongEngine.queryService().getInstance(instanceId);
        if (null == instance) {
            log.info("未找到流程实例,发起失败");
            return false;
        }
        feiShuConfigProperties.getApps().forEach((item, config) -> {
            try {
                SynchronizationApprovalDTO dto = new SynchronizationApprovalDTO();
                dto.setTenantKey(config.getTenantKey());
                dto.setApprovalCode(getApprovalCode(config.getTenantKey(), instance.getProcessId()));
                dto.setContractId(String.valueOf(contractId));
                dto.setInstanceStatus(FeiShuInstanceStatus.PENDING.getKey());
                dto.setInstanceId(String.valueOf(instanceId));
                dto.setTitle(contractName);
                dto.setApplyUserId(applyPeople);
                dto.setStartTime(instance.getCreateTime());
                dto.setEndTime(null);
                dto.setUpdateTime(new Date());
                dto.setForms(buildFormList(contractId));
                feiShuApproval.synchronizationApproval(dto);
                log.info("同步审批成功");

            } catch (Exception e) {
                log.error("同步审批失败", e);
            }
        });

        return null;
    }

    @Override
    public Boolean syncTask(TaskEventType eventType, Supplier<FlwTask> supplier, List<FlwTaskActor> taskActors, FlowCreator flowCreator, Integer count) {
        // 获取当前的任务
        FlwTask flwTask = supplier.get();
        if (null == flwTask) {
            log.warn("当前任务为空，同步任务失败");
            return false;
        }

        log.info("开始同步任务到飞书，事件类型：{}，任务ID：{}", eventType, flwTask.getId());

        try {
            // 获取流程实例
            FlwHisInstance histInstance = flowLongEngine.queryService().getHistInstance(flwTask.getInstanceId());
            if (null == histInstance ) {
                log.warn("未找到流程实例，同步失败");
                if (count > 5) {
                    log.warn("尝试同步任务失败，请检查流程实例是否正常");
                    return false;
                }
                Thread.sleep(100);
                syncTask(eventType, supplier, taskActors, flowCreator, count + 1);
            }

            // 获取关联的合同信息

            Integer contractId = null;
            try {
                contractId = Integer.parseInt(histInstance.getBusinessKey());
            } catch (Exception e) {
                log.warn("未找到关联的合同，同步失败");
                return false;
            }


            String contractName = contractFieldValueMapper.getFieldValueByCode(contractId, SystemFieldsEnum.CONTRACT_NAME.getCode());
            if (!StringUtils.hasText(contractName)) {
                contractName = "未知合同";
            }

            String applyPeople = contractFieldValueMapper.getFieldValueByCode(contractId, SystemFieldsEnum.APPLY_PEOPLE.getCode());

            // 根据不同的事件类型进行不同的同步处理
            String finalContractName = contractName;
            Integer finalContractId = contractId;
            feiShuConfigProperties.getApps().forEach((item, config) -> {
                try {
                    SynchronizationApprovalDTO dto = new SynchronizationApprovalDTO();
                    dto.setTenantKey(config.getTenantKey());
                    dto.setAppId(config.getAppId());
                    dto.setApprovalCode(getApprovalCode(config.getTenantKey(), histInstance.getProcessId()));
                    dto.setInstanceId(String.valueOf(flwTask.getInstanceId()));
                    dto.setTitle(finalContractName);
                    dto.setApplyUserId(applyPeople);
                    dto.setStartTime(histInstance.getCreateTime());
                    dto.setUpdateTime(new Date());
                    dto.setForms(buildFormList(finalContractId));
                    dto.setContractId(String.valueOf(finalContractId));
                    dto.setTaskId(String.valueOf(flwTask.getId()));

                    // 根据事件类型设置不同的数据
                    switch (eventType) {
                        case start:
                        case startAsDraft:
                        case restart:
                            log.info("流程任务启动，同步流程实例");
                            dto.setInstanceStatus(FeiShuInstanceStatus.PENDING.getKey());
                            break;
                        case cc:
                        case createCc:
                            // 抄送事件：同步抄送任务
                            log.info("处理抄送事件，同步抄送任务");
                            dto.setInstanceStatus(FeiShuInstanceStatus.PENDING.getKey());
                            dto.setCcTasks(buildCcTask(flwTask, taskActors, finalContractName));
                            break;

                        case create:
                        case assignment:
                        case recreate:
                            // 任务创建事件：同步普通任务
                            log.info("处理任务创建事件，同步普通任务");
                            dto.setInstanceStatus(FeiShuInstanceStatus.PENDING.getKey());
                            dto.setTasks(createTask(flwTask, taskActors, finalContractName));
                            break;

                        case complete:
                        case autoComplete:
                            // 任务完成事件：更新任务状态为完成
                            log.info("处理任务完成事件，更新任务状态");
                            dto.setInstanceStatus(FeiShuInstanceStatus.PENDING.getKey());
                            dto.setTasks(completedTask(flwTask, taskActors, flowCreator, finalContractName));
                            break;

                        case reject:
                        case autoReject:
                            // 任务驳回事件：更新任务状态为驳回
                            log.info("处理任务驳回事件，更新任务状态");
                            dto.setInstanceStatus(FeiShuInstanceStatus.PENDING.getKey());
                            dto.setTasks(rejectedTask(flwTask, taskActors, flowCreator, finalContractName));
                            break;

                        case revoke:
                        case withdraw:
                            // 撤回事件：更新实例状态为撤回
                            log.info("处理撤回事件，更新实例状态");
                            dto.setInstanceStatus(FeiShuInstanceStatus.CANCELED.getKey());
                            dto.setEndTime(new Date());
                            break;

                        case terminate:
                            // 终止事件：更新实例状态为终止
                            log.info("处理终止事件，更新实例状态");
                            dto.setInstanceStatus(FeiShuInstanceStatus.TERMINATED.getKey());
                            dto.setEndTime(new Date());
                            break;

                        case delete:
                            // 删除事件：更新实例状态为删除
                            log.info("处理删除事件，更新实例状态");
                            dto.setInstanceStatus(FeiShuInstanceStatus.DELETED.getKey());
                            dto.setEndTime(new Date());
                            break;

                        case addTaskActor:
                            // 加签事件：添加新的任务处理人
                            log.info("处理加签事件，添加新任务");
                            dto.setInstanceStatus(FeiShuInstanceStatus.PENDING.getKey());
                            dto.setTasks(addTaskActorTask(flwTask, taskActors, finalContractName));
                            break;

                        case removeTaskActor:
                            // 减签事件：移除任务处理人，更新任务状态
                            log.info("处理减签事件，更新任务");
                            dto.setInstanceStatus(FeiShuInstanceStatus.PENDING.getKey());
                            dto.setTasks(removeTaskActorTask(flwTask, taskActors, finalContractName));
                            break;

                        case claimRole:
                        case claimDepartment:
                            // 认领事件：更新任务处理人
                            log.info("处理认领事件，更新任务处理人");
                            dto.setInstanceStatus(FeiShuInstanceStatus.PENDING.getKey());
                            dto.setTasks(claimedTask(flwTask, taskActors, finalContractName));
                            break;
                        case end:
                            log.info("任务流程结束，全部节点通过");
                            dto.setInstanceStatus(FeiShuInstanceStatus.APPROVED.getKey());
                            break;
                        case other:
                            log.info("处理其他事件：{}，默认同步任务信息", eventType);
                            dto.setInstanceStatus(FeiShuInstanceStatus.PENDING.getKey());
                            dto.setTasks(otherTask(flwTask, taskActors, finalContractName));
                        default:
                            // 其他事件：默认同步任务信息
                            log.info("处理其他事件：{}，默认同步任务信息", eventType);
                            dto.setInstanceStatus(FeiShuInstanceStatus.PENDING.getKey());
                            break;
                    }

                    // 调用飞书API同步数据
                    feiShuApproval.synchronizationApproval(dto);
                    log.info("【{}】同步任务成功，事件类型：{}，任务ID：{}", config.getName(), eventType, flwTask.getId());

                } catch (Exception e) {
                    log.error("【{}】同步任务失败，事件类型：{}，任务ID：{}", config.getName(), eventType, flwTask.getId(), e);
                }
            });

            return true;

        } catch (Exception e) {
            log.error("同步任务到飞书失败，事件类型：{}，任务ID：{}", eventType, flwTask.getId(), e);
            return false;
        }
    }



    @Override
    public void terminateApproval(InstanceEventType eventType, Supplier<FlwHisInstance> supplier, FlowCreator flowCreator) {
        FlwHisInstance hisInstance = supplier.get();
        if (null == hisInstance) {
            log.warn("历史流程实例为空，终止审批失败");
            return;
        }

        try {
            Thread.sleep(3000);
            log.info("等待1秒,防止更新其他任务覆盖当前终止状态");
        }catch (Exception e){
            log.warn("线程等待报错");
        }

        log.info("开始终止飞书审批，事件类型：{}，实例ID：{}", eventType, hisInstance.getId());

        try {
            // 获取关联的合同信息
            Integer contractId = getContractIdByInstanceId(hisInstance.getId());
            if (null == contractId) {
                log.warn("未找到关联的合同，终止审批失败");
                return;
            }

            String contractName = contractFieldValueMapper.getFieldValueByCode(contractId, SystemFieldsEnum.CONTRACT_NAME.getCode());
            if (!StringUtils.hasText(contractName)) {
                contractName = "未知合同";
            }
            String applyPeople = contractFieldValueMapper.getFieldValueByCode(contractId, SystemFieldsEnum.APPLY_PEOPLE.getCode());

            // 遍历所有飞书配置并同步终止状态
            String finalContractName = contractName;
            feiShuConfigProperties.getApps().forEach((item, config) -> {
                try {
                    SynchronizationApprovalDTO dto = new SynchronizationApprovalDTO();
                    dto.setTenantKey(config.getTenantKey());
                    dto.setApprovalCode(getApprovalCode(config.getTenantKey(), hisInstance.getProcessId()));
                    dto.setInstanceId(String.valueOf(hisInstance.getId()));
                    dto.setTitle(finalContractName);
                    dto.setApplyUserId(applyPeople);
                    dto.setStartTime(hisInstance.getCreateTime());
                    dto.setContractId(String.valueOf(contractId));
                    dto.setUpdateTime(new Date());
                    dto.setEndTime(new Date()); // 设置结束时间

                    // 构建表单数据
                    dto.setForms(buildFormList(contractId));

                    // 根据事件类型设置状态
                    switch (eventType) {
                        case end:
                            log.info("任务流程结束，全部节点通过");
                            dto.setInstanceStatus(FeiShuInstanceStatus.APPROVED.getKey());
                            break;
                        case rejectComplete:
                            // 终止事件：更新实例状态为终止
                            log.info("处理终止事件，更新实例状态为终止");
                            dto.setInstanceStatus(FeiShuInstanceStatus.REJECTED.getKey());
                            break;
                        default:
                            // 默认设置为终止状态
                            log.info("处理其他终止事件：{}，默认设置为终止状态", eventType);
                            dto.setInstanceStatus(FeiShuInstanceStatus.TERMINATED.getKey());
                            break;
                    }

                    // 调用飞书API同步数据
                    feiShuApproval.synchronizationApproval(dto);
                    log.info("【{}】终止审批同步成功，事件类型：{}，实例ID：{}",
                            config.getName(), eventType, hisInstance.getId());

                } catch (Exception e) {
                    log.error("【{}】终止审批同步失败，事件类型：{}，实例ID：{}",
                            config.getName(), eventType, hisInstance.getId(), e);
                }
            });

        } catch (Exception e) {
            log.error("终止飞书审批失败，事件类型：{}，实例ID：{}", eventType, hisInstance.getId(), e);
        }
    }

    @Override
    public void sendApprovalBot(TaskEventType eventType, Supplier<FlwTask> supplier, List<FlwTaskActor> taskActors, FlowCreator flowCreator) {
        if (TaskEventType.create.eq(eventType) || TaskEventType.recreate.eq(eventType)) {
            FlwTask flwTask = supplier.get();
            if (null == flwTask) {
                log.warn("任务不存在，发送飞书机器人失败");
            }
            Integer contractId = getContractIdByInstanceId(flwTask.getInstanceId());
            if (null == contractId) {
                log.warn("无法找到关联的合同,发送飞书机器人失败");
                return;
            }
            FlwHisInstance hisInstance = flowLongEngine.queryService().getHistInstance(flwTask.getInstanceId());
            if (null == hisInstance){
                log.warn("历史流程实例为空，发送飞书机器人失败");
            }
            String contractName = contractFieldValueMapper.getFieldValueByCode(contractId, SystemFieldsEnum.CONTRACT_NAME.getCode());
            String contractNumber = contractFieldValueMapper.getFieldValueByCode(contractId, SystemFieldsEnum.CONTRACT_NUMBER.getCode());
            String contractType = contractFieldValueMapper.getFieldValueByCode(contractId, SystemFieldsEnum.CONTRACT_TYPE.getCode());
            String taskName = flwTask.getTaskName();
            if (StringUtils.hasText(contractType)) {
                try {
                    ContractTypeEntity type = contractTypeMapper.selectById(Integer.parseInt(contractType));
                    if (null != type) {
                        contractType = type.getTypeName();
                    }
                } catch (Exception e) {
                    log.error("合同类型ID格式错误: {}", contractType, e);
                    contractType = "未知合同类型";
                }
            } else {
                contractType = "未知合同类型";
            }
            String applyPeople = contractFieldValueMapper.getFieldValueByCode(contractId, SystemFieldsEnum.APPLY_PEOPLE.getCode());
            ArrayList<String> summary = new ArrayList<>();
            summary.add("合同名称：【" + (StringUtils.hasText(contractName) ? contractName : "未知合同名称") + "】");
            summary.add("合同编号：【" + (StringUtils.hasText(contractNumber) ? contractNumber : "未知合同编号") + "】");
            summary.add("合同类型：【" + contractType + "】");
            summary.add("当前节点：【" + taskName + "】");

            feiShuConfigProperties.getApps().forEach((item, config) -> {
                ArrayList<FeiShuApprovalMessage> feiShuMessage = new ArrayList<>();
                taskActors.forEach(taskActor -> {
                    SendFeiShuBotDTO sendFeiShuBotDTO = new SendFeiShuBotDTO();
                    sendFeiShuBotDTO.setAppId(config.getAppId());
                    sendFeiShuBotDTO.setContractId(String.valueOf(contractId));
                    sendFeiShuBotDTO.setInstanceId(String.valueOf(flwTask.getInstanceId()));
                    sendFeiShuBotDTO.setInstanceStatus(String.valueOf(hisInstance.getInstanceState()));
                    sendFeiShuBotDTO.setTaskId(String.valueOf(flwTask.getId()));
                    sendFeiShuBotDTO.setTenantKey(config.getTenantKey());
                    sendFeiShuBotDTO.setApprovalName(StringUtils.hasText(contractName) ? contractName : "未知合同");
                    sendFeiShuBotDTO.setUserId(taskActor.getActorId());
                    sendFeiShuBotDTO.setSummary(summary);
                    sendFeiShuBotDTO.setApplyUserId(applyPeople);
                    sendFeiShuBotDTO.setToken(new SSOToken()
                            .id(taskActor.getActorId())
                            .issuer(taskActor.getActorName() == null ? null : taskActor.getActorName())
                            .getToken());
                    try {
                        String messageId = feiShuApproval.sendApproval(sendFeiShuBotDTO);
                        if (StringUtils.hasText(messageId)) {
                            FeiShuApprovalMessage feiShuApprovalMessage = new FeiShuApprovalMessage();
                            feiShuApprovalMessage.setFlwTaskId(flwTask.getId());
                            feiShuApprovalMessage.setTenantKey(config.getTenantKey());
                            feiShuApprovalMessage.setMessageId(messageId);
                            feiShuApprovalMessage.setCreatorId(Long.parseLong(taskActor.getActorId()));
                            feiShuApprovalMessage.setCreateTime(new Date());
                            feiShuMessage.add(feiShuApprovalMessage);
                        }
                        log.info("发送飞书机器人成功");
                    } catch (Exception e) {
                        log.error("发送飞书机器人失败", e);
                    }
                });
                if (!CollectionUtils.isEmpty(feiShuMessage)) {
                    feiShuApprovalMessageMapper.insert(feiShuMessage);
                }

            });
        }
    }

    @Override
    public void syncApprovalBot(Long taskId, TaskEventType eventType, FlowCreator flowCreator) {
        List<FeiShuApprovalMessage> feiShuApprovalMessages = feiShuApprovalMessageMapper.selectList(Wrappers.<FeiShuApprovalMessage>lambdaQuery()
                .eq(FeiShuApprovalMessage::getFlwTaskId, taskId));
        if (CollectionUtils.isEmpty(feiShuApprovalMessages)) {
            log.warn("飞书消息不存在");
        }
        Long operatorUserId = null;
        try {
            operatorUserId = Long.parseLong(flowCreator.getCreateId());
        } catch (Exception e) {
            log.warn("操作人ID转换失败，flowCreator.getCreateId()={}", flowCreator.getCreateId());
        }

        final String operatorStatus = resolveActionStatus(eventType);

        Long finalOperatorUserId = operatorUserId;
        feiShuApprovalMessages.forEach(message -> {
            try {
                String statusToSet;
                if (finalOperatorUserId != null && finalOperatorUserId.equals(message.getCreatorId())) {
                    // 操作人的操作设置为操作内容（如 APPROVED/REJECTED）
                    statusToSet = operatorStatus;
                } else {
                    // 其他人的操作设置为已处理
                    statusToSet = "PROCESSED";
                }
                feiShuApproval.updateApproval(message.getTenantKey(), message.getMessageId(), statusToSet);
            } catch (Exception e) {
                log.error("【{}】下的【{}】消息同步飞书审批失败", message.getTenantKey(), message.getMessageId(), e);
            }
        });

    }

    private String resolveActionStatus(TaskEventType eventType) {
        if (eventType == null) {
            return "PROCESSED";
        }
        switch (eventType) {
            case complete:
            case autoComplete:
                return "APPROVED";
            case reject:
            case autoReject:
                return "REJECTED";
            default:
                return "PROCESSED";
        }
    }


    private Integer getContractIdByInstanceId(Long instanceId) {
        if (null == instanceId) {
            return null;
        }
        FlwInstance instance = flowLongEngine.queryService().getInstance(instanceId);
        FlwHisInstance histInstance = flowLongEngine.queryService().getHistInstance(instanceId);
        if (instance == null && histInstance == null) {
            log.warn("流程实例与历史实例均为空，无法解析关联合同，instanceId={}", instanceId);
            return null;
        }
        try {
            String businessKey = (instance != null && StringUtils.hasText(instance.getBusinessKey()))
                    ? instance.getBusinessKey()
                    : (histInstance != null ? histInstance.getBusinessKey() : null);
            if (!StringUtils.hasText(businessKey)) {
                log.warn("实例业务标识为空，无法解析关联合同，instanceId={}", instanceId);
                return null;
            }
            return Integer.parseInt(businessKey);
        } catch (Exception e) {
            log.warn("业务标识解析失败，无法解析关联合同，instanceId={}", instanceId, e);
            return null;
        }
    }

    private String getApprovalCode(String tenantKey, Long processId) {
        FlwProcessConfigure configure = flwProcessConfigureService.getOne(Wrappers.<FlwProcessConfigure>lambdaQuery()
                .eq(FlwProcessConfigure::getProcessId, processId)
                .last("limit 1"));
        if (null == configure) {
            return null;
        }
        Long categoryId = configure.getCategoryId();
        return getApprovalCode(tenantKey, processId, categoryId);
    }

    private String getApprovalCode(String tenantKey, Long processId, Long categoryId) {
        FlwProcess process = flwProcessService.getById(processId);
        if (null == process) {
            return null;
        }
        FeiShuApprovalCode feiShuApprovalCode = feiShuApprovalCodeMapper.selectByUniqueKey(categoryId, process.getProcessKey(), tenantKey);
        return null == feiShuApprovalCode ? null : feiShuApprovalCode.getApprovalCode();
    }

    private List<SynchronizationApprovalDTO.Form> buildFormList(Integer contractId) {
        ArrayList<SynchronizationApprovalDTO.Form> result = new ArrayList<>();
        result.add(buildForm(contractId, SystemFieldsEnum.CONTRACT_NAME, "未知合同"));
        result.add(buildForm(contractId, SystemFieldsEnum.CONTRACT_NUMBER, "暂无编号"));
        result.add(buildForm(contractId, SystemFieldsEnum.CONTRACT_TYPE, "未知类型"));
        return result;
    }

    private SynchronizationApprovalDTO.Form buildForm(Integer contractId, SystemFieldsEnum systemFieldsEnum, String defaultValue) {
        SynchronizationApprovalDTO.Form form = new SynchronizationApprovalDTO.Form();
        form.setName(systemFieldsEnum.getFieldName());

        if (systemFieldsEnum.equals(SystemFieldsEnum.CONTRACT_TYPE)) {
            String contractType = contractFieldValueMapper.getFieldValueByCode(contractId, systemFieldsEnum.getCode());
            if (StringUtils.hasText(contractType)) {
                ContractTypeEntity contractTypeEntity = contractTypeMapper.selectOne(Wrappers.<ContractTypeEntity>lambdaQuery()
                        .eq(ContractTypeEntity::getId, contractType)
                        .last("limit 1"));
                if (null != contractTypeEntity && StringUtils.hasText(contractTypeEntity.getTypeName())) {
                    form.setValue(contractTypeEntity.getTypeName());
                    return form;
                }
            }
        }

        String fieldValue = contractFieldValueMapper.getFieldValueByCode(contractId, systemFieldsEnum.getCode());
        form.setValue(StringUtils.hasText(fieldValue) ? fieldValue : defaultValue);
        return form;
    }


    private List<SynchronizationApprovalDTO.CcTask> buildCcTask(FlwTask flwTask, List<FlwTaskActor> taskActors, String contractName) {
        ArrayList<SynchronizationApprovalDTO.CcTask> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(taskActors)) {
            return result;
        }
        taskActors.forEach(taskActor -> {
            SynchronizationApprovalDTO.CcTask ccTask = new SynchronizationApprovalDTO.CcTask();
            ccTask.setCcId(String.valueOf(taskActor.getId()));
            ccTask.setCcUserId(taskActor.getActorId());
            ccTask.setReadStatus("UNREAD");
            ccTask.setTitle(contractName);
            ccTask.setCreateTime(flwTask.getCreateTime());
            ccTask.setUpdateTime(new Date());
            result.add(ccTask);
        });
        return result;
    }

    private List<SynchronizationApprovalDTO.Task> createTask(FlwTask flwTask, List<FlwTaskActor> taskActors, String contractName) {
        ArrayList<SynchronizationApprovalDTO.Task> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(taskActors)) {
            return result;
        }
        taskActors.forEach(taskActor -> {
            SynchronizationApprovalDTO.Task feiShuTask = new SynchronizationApprovalDTO.Task();
            feiShuTask.setTaskId(String.valueOf(taskActor.getId()));
            feiShuTask.setTaskTitle(contractName);
            feiShuTask.setTaskUserId(taskActor.getActorId());
            feiShuTask.setTaskStatus(FeiShuTaskStatus.PENDING.getKey());
            feiShuTask.setStartTime(flwTask.getCreateTime());
            feiShuTask.setEndTime(null);
            feiShuTask.setUpdateTime(new Date());
            feiShuTask.setNodeId(flwTask.getTaskKey());
            feiShuTask.setNodeName(flwTask.getTaskName());
            result.add(feiShuTask);
        });
        return result;
    }

    private List<SynchronizationApprovalDTO.Task> completedTask(FlwTask flwTask, List<FlwTaskActor> taskActors, FlowCreator flowCreator, String contractName) {
        ArrayList<SynchronizationApprovalDTO.Task> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(taskActors)) {
            return result;
        }
        List<FlwTaskActor> complete = taskActors.stream().filter(taskActor -> taskActor.getActorId().equals(flowCreator.getCreateId())).toList();
        if (!CollectionUtils.isEmpty(complete)) {
            complete.forEach(taskActor -> {
                SynchronizationApprovalDTO.Task feiShuTask = new SynchronizationApprovalDTO.Task();
                feiShuTask.setTaskId(String.valueOf(taskActor.getId()));
                feiShuTask.setTaskTitle(contractName);
                feiShuTask.setTaskUserId(taskActor.getActorId());
                feiShuTask.setTaskStatus(FeiShuTaskStatus.APPROVED.getKey());
                feiShuTask.setExtra("{\"complete_reason\":\"approved\"}");
                feiShuTask.setStartTime(flwTask.getCreateTime());
                feiShuTask.setEndTime(new Date());
                feiShuTask.setUpdateTime(new Date());
                feiShuTask.setNodeId(flwTask.getTaskKey());
                feiShuTask.setNodeName(flwTask.getTaskName());
                result.add(feiShuTask);
            });
        }
        List<FlwTaskActor> done = taskActors.stream().filter(taskActor -> !taskActor.getActorId().equals(flowCreator.getCreateId())).toList();
        if (!CollectionUtils.isEmpty(done)) {
            done.forEach(taskActor -> {
                SynchronizationApprovalDTO.Task feiShuTask = new SynchronizationApprovalDTO.Task();
                feiShuTask.setTaskId(String.valueOf(taskActor.getId()));
                feiShuTask.setTaskTitle(contractName);
                feiShuTask.setTaskUserId(taskActor.getActorId());
                feiShuTask.setTaskStatus(FeiShuTaskStatus.DONE.getKey());
                feiShuTask.setExtra("{\"complete_reason\":\"approved\"}");
                feiShuTask.setStartTime(flwTask.getCreateTime());
                feiShuTask.setEndTime(new Date());
                feiShuTask.setUpdateTime(new Date());
                feiShuTask.setNodeId(flwTask.getTaskKey());
                feiShuTask.setNodeName(flwTask.getTaskName());
                result.add(feiShuTask);
            });
        }
        return result;
    }

    private List<SynchronizationApprovalDTO.Task> rejectedTask(FlwTask flwTask, List<FlwTaskActor> taskActors, FlowCreator flowCreator, String contractName) {
        ArrayList<SynchronizationApprovalDTO.Task> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(taskActors)) {
            return result;
        }
        List<FlwTaskActor> rejected = taskActors.stream().filter(taskActor -> taskActor.getActorId().equals(flowCreator.getCreateId())).toList();
        if (!CollectionUtils.isEmpty(rejected)) {
            rejected.forEach(taskActor -> {
                SynchronizationApprovalDTO.Task feiShuTask = new SynchronizationApprovalDTO.Task();
                feiShuTask.setTaskId(String.valueOf(taskActor.getId()));
                feiShuTask.setTaskTitle(contractName);
                feiShuTask.setTaskUserId(taskActor.getActorId());
                feiShuTask.setTaskStatus(FeiShuTaskStatus.REJECTED.getKey());
                feiShuTask.setExtra("{\"reject_reason\":\"rejected\"}");
                feiShuTask.setStartTime(flwTask.getCreateTime());
                feiShuTask.setEndTime(new Date());
                feiShuTask.setUpdateTime(new Date());
                feiShuTask.setNodeId(flwTask.getTaskKey());
                feiShuTask.setNodeName(flwTask.getTaskName());
                result.add(feiShuTask);
            });
        }
        List<FlwTaskActor> done = taskActors.stream().filter(taskActor -> !taskActor.getActorId().equals(flowCreator.getCreateId())).toList();
        if (!CollectionUtils.isEmpty(done)) {
            done.forEach(taskActor -> {
                SynchronizationApprovalDTO.Task feiShuTask = new SynchronizationApprovalDTO.Task();
                feiShuTask.setTaskId(String.valueOf(taskActor.getId()));
                feiShuTask.setTaskTitle(contractName);
                feiShuTask.setTaskUserId(taskActor.getActorId());
                feiShuTask.setTaskStatus(FeiShuTaskStatus.DONE.getKey());
                feiShuTask.setExtra("{\"reject_reason\":\"rejected\"}");
                feiShuTask.setStartTime(flwTask.getCreateTime());
                feiShuTask.setEndTime(new Date());
                feiShuTask.setUpdateTime(new Date());
                feiShuTask.setNodeId(flwTask.getTaskKey());
                feiShuTask.setNodeName(flwTask.getTaskName());
                result.add(feiShuTask);
            });
        }
        return result;
    }

    private List<SynchronizationApprovalDTO.Task> addTaskActorTask(FlwTask flwTask, List<FlwTaskActor> taskActors, String contractName) {
        ArrayList<SynchronizationApprovalDTO.Task> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(taskActors)) {
            return result;
        }
        taskActors.forEach(taskActor -> {
            SynchronizationApprovalDTO.Task feiShuTask = new SynchronizationApprovalDTO.Task();
            feiShuTask.setTaskId(String.valueOf(taskActor.getId()));
            feiShuTask.setTaskTitle(contractName);
            feiShuTask.setTaskUserId(taskActor.getActorId());
            feiShuTask.setTaskStatus(FeiShuTaskStatus.PENDING.getKey());
            feiShuTask.setExtra("{\"action\":\"add_task_actor\"}");
            feiShuTask.setStartTime(flwTask.getCreateTime());
            feiShuTask.setEndTime(null);
            feiShuTask.setUpdateTime(new Date());
            feiShuTask.setNodeId(flwTask.getTaskKey());
            feiShuTask.setNodeName(flwTask.getTaskName());
            result.add(feiShuTask);
        });
        return result;
    }

    private List<SynchronizationApprovalDTO.Task> removeTaskActorTask(FlwTask flwTask, List<FlwTaskActor> taskActors, String contractName) {
        ArrayList<SynchronizationApprovalDTO.Task> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(taskActors)) {
            return result;
        }
        taskActors.forEach(taskActor -> {
            SynchronizationApprovalDTO.Task feiShuTask = new SynchronizationApprovalDTO.Task();
            feiShuTask.setTaskId(String.valueOf(taskActor.getId()));
            feiShuTask.setTaskTitle(contractName);
            feiShuTask.setTaskUserId(taskActor.getActorId());
            feiShuTask.setTaskStatus(FeiShuTaskStatus.DONE.getKey());
            feiShuTask.setExtra("{\"action\":\"remove_task_actor\",\"complete_reason\":\"delete_assignee\"}");
            feiShuTask.setStartTime(flwTask.getCreateTime());
            feiShuTask.setEndTime(new Date());
            feiShuTask.setUpdateTime(new Date());
            feiShuTask.setNodeId(flwTask.getTaskKey());
            feiShuTask.setNodeName(flwTask.getTaskName());
            result.add(feiShuTask);
        });
        return result;
    }

    private List<SynchronizationApprovalDTO.Task> claimedTask(FlwTask flwTask, List<FlwTaskActor> taskActors, String contractName) {
        ArrayList<SynchronizationApprovalDTO.Task> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(taskActors)) {
            return result;
        }
        taskActors.forEach(taskActor -> {
            SynchronizationApprovalDTO.Task feiShuTask = new SynchronizationApprovalDTO.Task();
            feiShuTask.setTaskId(String.valueOf(taskActor.getId()));
            feiShuTask.setTaskTitle(contractName);
            feiShuTask.setTaskUserId(taskActor.getActorId());
            feiShuTask.setTaskStatus(FeiShuTaskStatus.PENDING.getKey());
            feiShuTask.setExtra("{\"action\":\"claimed\"}");
            feiShuTask.setStartTime(flwTask.getCreateTime());
            feiShuTask.setEndTime(null);
            feiShuTask.setUpdateTime(new Date());
            feiShuTask.setNodeId(flwTask.getTaskKey());
            feiShuTask.setNodeName(flwTask.getTaskName());
            result.add(feiShuTask);
        });
        return result;
    }

    private List<SynchronizationApprovalDTO.Task> otherTask(FlwTask flwTask, List<FlwTaskActor> taskActors, String contractName) {
        ArrayList<SynchronizationApprovalDTO.Task> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(taskActors)) {
            return result;
        }
        taskActors.forEach(taskActor -> {
            SynchronizationApprovalDTO.Task feiShuTask = new SynchronizationApprovalDTO.Task();
            feiShuTask.setTaskId(String.valueOf(taskActor.getId()));
            feiShuTask.setTaskTitle(contractName);
            feiShuTask.setTaskUserId(taskActor.getActorId());
            feiShuTask.setTaskStatus(FeiShuTaskStatus.DONE.getKey());
            feiShuTask.setExtra("{\"complete_reason\":\"others\"}");
            feiShuTask.setStartTime(flwTask.getCreateTime());
            feiShuTask.setEndTime(new Date());
            feiShuTask.setUpdateTime(new Date());
            feiShuTask.setNodeId(flwTask.getTaskKey());
            feiShuTask.setNodeName(flwTask.getTaskName());
            result.add(feiShuTask);
        });
        return result;
    }

}
